package org.example.design.template.utils;

import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.example.bean.enums.ExcelStyleEnum;
import org.example.util.Function;

import java.io.OutputStream;
import java.util.List;

/**
 * @author huangshen
 * @version 0
 * @description POIExcelExportHSFImp
 * @since 2022/2/3 15:47
 */
public class POIExcelExportHSFImp implements IExcelExportUtil{
    private static final String TITLE = "title";
    private static final String COLOR = "color";

    private Integer rowNumSign = 0;
    private Integer rowNum = 0;
    /**
     *  单元格是否为超链接标志
     */
    private boolean linkFlag = false;
    /**
     *  参数数量
     */
    private final Integer paramSize;
    /**
     *  HSSF工具
     */
    private HssfExcelUtils xsf;
    /**
     *  HSSF单元格样式
     */
    private HSSFCellStyle cellStyle;
    /**
     *  HSSF超链接路径
     */
    private String linkPath;
    /**
     *  Excel标题
     */
    private final String excelTitle;
    /**
     *  参数名集合
     */
    private List<String> paramNameList;
    /**
     *  样式参数
     */
    private ExcelStyle styleValue;
    /**
     * 构造函数 初始化数据
     * @param paramSize 参数个数
     * @param excelTitle excel标题
     */
    public POIExcelExportHSFImp(String excelTitle, Integer paramSize){
        this.excelTitle = excelTitle;
        // 通过反射获取参数数量
        this.paramSize =  paramSize;
    }

    /**
     * 初始化Excel
     */
    @Override
    public void initExcel(){
        if(Function.equalsNull(styleValue)) {
            styleValue = new ExcelStyle();
        }
        xsf =  new HssfExcelUtils(paramSize, excelTitle, styleValue);
    }

    /**
     * 设置标题
     */
    @Override
    public void setTitle(String excelTitle) {
        // 设置标题
        xsf.setTitle(excelTitle, rowNum);
        // 设置样式
        this.setCellStyle(TITLE);
        // 标题行高
        xsf.setRowHeight(rowNum, styleValue.getTitleRowHeight());
        // 设置标题样式
        xsf.getSheet().getRow(rowNum).getCell(0).setCellStyle(cellStyle);

        rowNum ++;
    }

    /**
     * 设置列名
     */
    @Override
    public void setColName(List<String> paramNameList){
        this.paramNameList = paramNameList;
        for(int i = 0; i < paramSize; i++){
            xsf.setCellWidth(i, styleValue.getColumnNameCellWidth());
        }
        // 不显示网格
        xsf.setDisplayGrid(false);
        // 设置网格样式
        this.setCellStyle(TITLE);
        // 设置列名
        for (int i = 0; i < paramNameList.size(); i ++){
            xsf.setMergedCell(cellStyle, rowNum, i, paramNameList.get(i));
        }
        rowNum ++;
    }

    /**
     * 设置单元格样式
     * @param cellType 单元格类型(标题/普通单元格）
     */
    @Override
    public void setCellStyle(String cellType){
        // 设置单元格样式
        this.cellStyle = xsf.getCellStyle();
    }

    /**
     * 设置超链接
     * @param linkPath 超链接路径
     */
    @Override
    public void setHyperLink(String linkPath){
        this.linkFlag = true;
        this.linkPath = linkPath;
    }

    /**
     * 设置单元格的数据
     * @param value 单元格数据
     * @param index 角标
     */
    @Override
    public void setRowData(String value, int index){
        try {
            // 设置单元格数据
            // 该单元格是否是超链接
            if(this.linkFlag){
                // 设置超链接单元格
                xsf.setHyperLinkCell(cellStyle, rowNum, index, value,styleValue.getColumnNameCellHeight(), linkPath);
                this.linkFlag = false;
                return;
            }
            // 插入普通单元格
            xsf.setMergedCell(cellStyle, rowNum, index, value);
            rowNumSign ++;

            if(rowNumSign.equals(paramSize)){
                rowNumSign = 0;
                rowNum ++;
            }
        } catch (Exception ioe) {
            ioe.printStackTrace();
        }
    }

    /**
     * 创建新一页
     * @param sheetName sheet名
     */
    @Override
    public void createSheet(String sheetName){
        rowNum = 0;
        // 创建sheet
        xsf.createSheet(paramSize, sheetName, true);
        // 设置标题
        this.setTitle(excelTitle);
        // 设置列名
        this.setColName(paramNameList);

        rowNum ++;
    }

    /**
     * 创建Excel
     * @param outputStream 文件输出流
     */
    @Override
    public void createExcel(OutputStream outputStream) {
        xsf.excel(outputStream);
    }

    @Override
    public IExcelExportUtil setStyleValue(ExcelStyle styleValue) {
        this.styleValue = styleValue;
        return this;
    }
}
